package com.yonyou.brigade.third_parties.bfjr.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yonyou.brigade.basic_init.enums.ChannelEnum;
import com.yonyou.brigade.basic_init.model.BriChannel;
import com.yonyou.brigade.basic_init.service.IBaseDocService;
import com.yonyou.brigade.basic_init.service.IBriChannelService;
import com.yonyou.brigade.basic_init.service.IUserCenterService;
import com.yonyou.brigade.order_center.model.ThirdResult;
import com.yonyou.brigade.third_parties.bfjr.model.BfjrConfig;
import com.yonyou.brigade.third_parties.bfjr.service.IBfjrPublicService;
import com.yonyou.brigade.util.HttpClientUtil;
import com.yonyou.brigade.util.operateutil.DateUtils;
import com.yonyou.brigade.util.operateutil.JsonUtils;
import com.yonyou.ybzboot.starter.common.exception.BaseException;
import com.yonyou.ybzboot.starter.common.exception.BusinessException;
import com.yonyou.ybzboot.starter.common.util.StringUtil;
import com.yonyou.ybzboot.uc.dto.UcUserDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
public class BfjrPublicServiceImpl implements IBfjrPublicService {

    private static Logger logger = LoggerFactory.getLogger(BfjrPublicServiceImpl.class);

    @Value("${bfjr.url.deptList}")
    private String deptListUrl;

    @Value("${bfjr.url.deptDel}")
    private String deptDelUrl;

    @Value("${bfjr.url.empBatchAdd}")
    private String empBatchAddUrl;

    @Value("${bfjr.url.employeeGet}")
    private String empQueryUrl;

    @Value("${bfjr.url.employeeDel}")
    private String empDelUrl;

    @Value("${bfjr.url.ssoUrl}")
    private String SSO_URL;

    @Value("${bfjr.url.applySyncUrl}")
    private String APPLYSYNCURL_URL;

    @Value("${ybz.baseUrl}")
    private String ybzBaseUrl;

    @Value("${ybz.getMnecode.url}")
    private String getMnecode;

    @Autowired
    private IUserCenterService userCenterService;

    @Autowired
    private IBaseDocService baseDocService;

    @Autowired
    private IBriChannelService briChannelService;

    @Override
    public JSONObject pushApplyOrder(BriChannel channel, String tenant, String org, JSONObject applyOrderJson) {
        logger.info("调用北方假日申请单同步接口，原始数据："+applyOrderJson);
        JSONObject result = new JSONObject();
        JSONObject reqData = processApplyData(channel, applyOrderJson, tenant);
        logger.info("北方假日申请单同步" + reqData.toJSONString());
        String strResult = HttpClientUtil.doPostJsonForm(APPLYSYNCURL_URL, reqData.toJSONString());
        logger.info("北方假日申请单同步结果" + strResult);
        if (!StringUtils.isEmpty(strResult) && JsonUtils.isJSONObject(strResult)) {
            JSONObject resultJSON = JSONObject.parseObject(strResult);
            if ("0".equals(resultJSON.getString("ret"))) {
                result.put("success", Boolean.TRUE);
            } else {
                result.put("success", Boolean.FALSE);
                result.put("msg", resultJSON.getString("msg"));
            }
        }
        return result;
    }

    private JSONObject processApplyData(BriChannel channel, JSONObject applyOrderJson, String tenant) {
        JSONObject applyData = new JSONObject();
        BfjrConfig bfjrConfig = JSONObject.parseObject(channel.getConfig(), BfjrConfig.class);
        String userId = applyOrderJson.getString("userId");
        List<String> userIds = new ArrayList<>();
        userIds.add(userId);
        List<UcUserDto> userDtoList = userCenterService.getCompleteUcUserDtoByUserid(userIds, tenant);
        if (CollectionUtils.isEmpty(userDtoList)) {
            logger.error("申请单同步失败，用户中心未找到对应人员信息：userId为" + userId + "；tenantId为" + tenant);
            return null;
        }
        UcUserDto ucUserDto = userDtoList.get(0);
        JSONObject special = applyOrderJson.getJSONObject("special");
        String openType = special.getString("openType");
        applyData.put("appId", bfjrConfig.getAppId());
        applyData.put("expBusiBillId", applyOrderJson.getString("billNum"));
        applyData.put("regExpEmpId", ucUserDto.getPersonCode());
        //0全部 1机票 2酒店 3火车票
        applyData.put("busiType", 1);
        applyData.put("arrTime", DateUtils.date2Str(applyOrderJson.getDate("startDate"), DateUtils.DD_DATE_FORMAT));
        applyData.put("backTime", DateUtils.date2Str(applyOrderJson.getDate("endDate"), DateUtils.DD_DATE_FORMAT));
        JSONArray detailList = getDetailList(special);
        applyData.put("detailList", detailList);
        JSONArray empList = getEmpList(applyOrderJson, tenant, openType, ucUserDto);
        applyData.put("empList", empList);
        JSONArray costCenterList = getCostCenterList(channel, applyOrderJson, tenant, userId, openType);
        applyData.put("costCenterList", costCenterList);
        return applyData;
    }

    private JSONArray getCostCenterList(BriChannel channel, JSONObject applyOrderJson, String tenant, String userId, String openType) {
        JSONArray costCenterList = new JSONArray();
        if (channel != null && channel.getSyncCostInfo() != 0) {
            //费用承担部门
            String assumeDept = applyOrderJson.getString("assumeDept");
            String[] assumeDeptArr = assumeDept != null ? assumeDept.split(",") : null;
            //费用承担单位
            String assumeOrg = applyOrderJson.getString("assumeOrg");
            String[] assumeOrgArr = assumeOrg != null ? assumeOrg.split(",") : null;
            //费用项目
            String costProject = applyOrderJson.getString("costProject");
            String[] costProjectArr = costProject != null ? costProject.split(",") : null;
            String assumeDeptValue = "";
            String assumeOrgValue = "";
            String assumeProjectValue = "";
            JSONObject paramJSON = new JSONObject();
            paramJSON.put("tenantId", tenant);
            paramJSON.put("userId", userId);
            switch (channel.getSyncCostInfo()) {
                //传名称
                case 1:
                    if (assumeDeptArr != null && assumeDeptArr.length > 0){
                        if (assumeDeptArr.length > 1){
                            assumeDeptValue = assumeDeptArr[1];
                        }else {
                            Map<String, String> deptInfo = baseDocService.getDeptByOsType(tenant, userId ,assumeDeptArr[0], openType);
                            assumeDeptValue = deptInfo != null ? deptInfo.get("name") : "";
                        }
                    }
                    if (assumeOrgArr != null && assumeOrgArr.length > 0){
                        if (assumeOrgArr.length > 1) {
                            assumeOrgValue = assumeOrgArr[1];
                        }else {
                            Map<String, String> orgInfo = baseDocService.getOrgByOsType(tenant, userId, assumeOrgArr[0], openType);
                            assumeOrgValue = orgInfo != null ? orgInfo.get("name") : "";
                        }
                    }
                    if (costProjectArr != null && costProjectArr.length > 0){
                        if (costProjectArr.length > 1){
                            assumeProjectValue = costProjectArr[1];
                        }else {
                            Map<String, String> projectInfo = baseDocService.getInOutProjectByOsType(tenant, userId, costProjectArr[0], openType);
                            assumeProjectValue = projectInfo != null ? projectInfo.get("name") : "";
                        }
                    }
                    break;
                //传pk
                case 2:
                    if (assumeDeptArr != null && assumeDeptArr.length > 0){
                        assumeDeptValue = assumeDeptArr[0];
                    }
                    if (assumeOrgArr != null && assumeOrgArr.length > 0){
                        assumeOrgValue = assumeOrgArr[0];
                    }
                    if (costProjectArr != null && costProjectArr.length > 0){
                        assumeProjectValue = costProjectArr[0];
                    }
                    break;
                case 3:
                    if (assumeDeptArr != null && assumeDeptArr.length > 0){
                        assumeDeptValue = assumeDeptArr[0];
                        paramJSON.put("pk", assumeDeptValue);
                        paramJSON.put("docType", "dept");
                        String resultStr = HttpClientUtil.doPostJson(ybzBaseUrl + getMnecode + "?tenantId=" + tenant, JSON.toJSONString(paramJSON));
                        if (org.apache.commons.lang.StringUtils.isNotEmpty(resultStr)) {
                            try {
                                JSONObject resultJSON = JSONObject.parseObject(resultStr);
                                if (resultJSON != null && resultJSON.getJSONObject("baseDocResult") != null) {
                                    String name = resultJSON.getJSONObject("baseDocResult").getString("name");
                                    String mnecode = resultJSON.getJSONObject("baseDocResult").getString("mnecode");
                                    assumeDeptValue = mnecode + " " + name;
                                }
                            } catch (Exception e) {
                                logger.error("getMnecode error : " + e.getMessage());
                            }
                        } else {
                            logger.error("getMnecode result is null, param: " + JSON.toJSONString(paramJSON));
                        }
                    }

                    if (assumeOrgArr != null && assumeOrgArr.length > 0){
                        if (assumeOrgArr.length > 1) {
                            assumeOrgValue = assumeOrgArr[1];
                        }else {
                            Map<String, String> orgInfo = baseDocService.getOrgByOsType(tenant, userId, assumeOrgArr[0], openType);
                            assumeOrgValue = orgInfo != null ? orgInfo.get("name") : "";
                        }
                    }

                    if (costProjectArr != null && costProjectArr.length > 0){
                        Map<String, String> projectInfo = baseDocService.getInOutProjectByOsType(tenant, userId, costProjectArr[0], openType);
                        assumeProjectValue = projectInfo != null ? projectInfo.get("code") + " " + projectInfo.get("name") : "";
                    }
                    break;
                default:
                    break;
            }
            if (assumeOrgArr != null && assumeOrgArr.length > 0 && org.apache.commons.lang.StringUtils.isNotEmpty(assumeOrgArr[0])) {
                JSONObject orgJSON = new JSONObject();
                orgJSON.put("typeId", 1);
                orgJSON.put("costCenterName", assumeOrgValue);
                costCenterList.add(orgJSON);
            }

            if (assumeDeptArr != null && assumeDeptArr.length > 0 && org.apache.commons.lang.StringUtils.isNotEmpty(assumeDeptArr[0])) {
                JSONObject orgJSON = new JSONObject();
                orgJSON.put("typeId", 2);
                orgJSON.put("costCenterName", assumeDeptValue);
                costCenterList.add(orgJSON);
            }
            if (costProjectArr != null && costProjectArr.length > 0 && org.apache.commons.lang.StringUtils.isNotEmpty(costProjectArr[0])) {
                JSONObject orgJSON = new JSONObject();
                orgJSON.put("typeId", 3);
                orgJSON.put("costCenterName", assumeProjectValue);
                costCenterList.add(orgJSON);
            }
        }
        return costCenterList;
    }

    private JSONArray getDetailList(JSONObject special) {
        JSONArray detailList = new JSONArray();
        JSONObject cityCodes = special.getJSONObject("cityCodes");
        if (cityCodes != null) {
            Set<String> cityNames = cityCodes.keySet();
            if (!CollectionUtils.isEmpty(cityNames)) {
                for (String cityName : cityNames) {
                    JSONObject city = new JSONObject();
                    city.put("city", cityName);
//                    city.put("cityCode", cityCodes.getString(cityName));
                    detailList.add(city);
                }
            }
        }
        return detailList;
    }

    private JSONArray getEmpList(JSONObject applyOrderJson, String tenant, String openType, UcUserDto ucUserDto) {
        JSONArray empList = new JSONArray();
        String actualPedestrian = applyOrderJson.getString("actualPedestrian");
        if (!StringUtils.isEmpty(actualPedestrian)) {
            String[] split = actualPedestrian.split(";");
            List<String> personIds = new ArrayList<>();
            for (String str : split) {
                if (str.split(",").length > 0) {
                    personIds.add(str.split(",")[0]);
                }
            }
            List<UcUserDto> companionUser = null;
            if ("nc".equals(openType)) {
                companionUser = userCenterService.getCompleteUcUserByPersonIds(personIds, tenant);
            } else {
                companionUser = userCenterService.getCompleteUcUserDtoByUserid(personIds, tenant);
            }
            if (!CollectionUtils.isEmpty(companionUser)) {
                for (UcUserDto companionDto : companionUser) {
                    JSONObject pasesenger = new JSONObject();
                    pasesenger.put("psgType", 0);
                    pasesenger.put("empName", companionDto.getUserName());
                    pasesenger.put("expEmpId", companionDto.getPersonCode());
                    empList.add(pasesenger);
                }
            } else {
                logger.info("用户中心未找到实际出行人:" + personIds.toString());
                //TODO 用户中心未找到人员时同步erp用户，再次查找。
                throw new BusinessException("用户中心未找到部分实际出行人");
            }
        }
        // 旧的实际出行人为手输格式，支持格式  张三,李四
        String companion = applyOrderJson.getString("companion");
        //如果手输格式人名和制单人名一致则忽略
        if (org.apache.commons.lang.StringUtils.isNotEmpty(companion) && !companion.equals(ucUserDto.getUserName())) {
            companion = companion.replaceAll("，", ",").replaceAll("、", ",").replaceAll("/", ",").replaceAll("。", ",").replaceAll(" ", "").trim();
            String[] splitCompanion = companion.split(",");
            for (String oneCompanion : splitCompanion) {
                if(org.apache.commons.lang.StringUtils.isNotBlank(oneCompanion)){
                    String[] strings = oneCompanion.split(":");
                    JSONObject pasesenger = new JSONObject();
                    pasesenger.put("psgType", 1);
                    pasesenger.put("empName", strings[0]);
                    empList.add(pasesenger);
                }
            }
        }
        //如果实际出行人为空，则同步提单人
        if (CollectionUtils.isEmpty(empList)) {
            JSONObject pasesenger = new JSONObject();
            pasesenger.put("psgType", 0);
            pasesenger.put("empName", ucUserDto.getUserName());
            pasesenger.put("expEmpId", ucUserDto.getPersonCode());
            empList.add(pasesenger);
        }
        return empList;
    }

    @Override
    public String ssoLogin(String pcode, JSONObject jsonObject, String pcOrH5) {
        StringBuffer urlBuffer = new StringBuffer();
        try {
            String appId = jsonObject.getString("appId");
                urlBuffer.append(SSO_URL)
                        .append("?").append("appId=")
                        .append(appId)
                        .append("&").append("type=0")
                        .append("&").append("order_user=")
                        .append(pcode);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            throw new BaseException(-100,e.getMessage());
        }
        return urlBuffer.toString();
    }

    /**
     * 北方假日部门信息查询
     * @param phone,tenant,appId
     * @return
     */
    @Override
    public ThirdResult queryDeptInfo(String phone,String tenant) {
        BriChannel enableChannelByOpenType = briChannelService.getEnableChannelByOpenType(tenant, ChannelEnum.BFJR.getName(), 2);
        String config = enableChannelByOpenType.getConfig();
        JSONObject configObject = JSONObject.parseObject(config);
        UcUserDto userDto = userCenterService.getCompleteUcUserDtoByPhone(phone, tenant);
        String url = deptListUrl;
        JSONObject requestParam = new JSONObject();
        requestParam.put("appId",configObject.getString("appId"));
        if (userDto != null) {
            requestParam.put("deptName",userDto.getDeptName());
        }
        logger.info("北方假日部门信息查询" + requestParam.toJSONString());
        String strResult = HttpClientUtil.doPostJsonForm(url, requestParam.toJSONString());
        logger.info("北方假日部门信息查询结果" + strResult);
        if (StringUtil.isNotEmpty(strResult)){
            JSONObject rs = JSONObject.parseObject(strResult);
            if ("0".equals(rs.getString("ret"))){
                return new ThirdResult(true, rs.getString("msg") );
            }else {
                return new ThirdResult(false, rs.getString("msg") );
            }
        }
        return new ThirdResult(false, strResult );

    }

    @Override
    public ThirdResult delDeptInfo(String phone,String tenant) {
        BriChannel enableChannelByOpenType = briChannelService.getEnableChannelByOpenType(tenant, ChannelEnum.BFJR.getName(), 2);
        String config = enableChannelByOpenType.getConfig();
        JSONObject configObject = JSONObject.parseObject(config);
        UcUserDto userDto = userCenterService.getCompleteUcUserDtoByPhone(phone, tenant);
        String url = deptDelUrl;
        JSONObject requestParam = new JSONObject();
        if (userDto == null) {
            return new ThirdResult(false,"通过手机号和租户查询的UcUserDto为空");
        }
        requestParam.put("appId",configObject.getString("appId"));
        requestParam.put("expDeptId",userDto.getOrgPk());
        logger.info("北方假日部门信息删除" + requestParam.toJSONString());
        String strResult = HttpClientUtil.doPostJsonForm(url, requestParam.toJSONString());
        logger.info("北方假日部门信息删除结果" + strResult);
        if (StringUtil.isNotEmpty(strResult)){
            JSONObject rs = JSONObject.parseObject(strResult);
            if ("0".equals(rs.getString("ret"))){
                return new ThirdResult(true, rs.getString("msg") );
            }else {
                return new ThirdResult(false, rs.getString("msg") );
            }
        }
        return new ThirdResult(false, strResult );

    }

    @Override
    public ThirdResult empBatchAdd(String tenant) {
        BriChannel enableChannelByOpenType = briChannelService.getEnableChannelByOpenType(tenant, ChannelEnum.BFJR.getName(), 2);
        String config = enableChannelByOpenType.getConfig();
        JSONObject configObject = JSONObject.parseObject(config);
        List<UcUserDto> ucUserDtoList =  userCenterService.getUcUsersByTenantId(tenant);
        String url = empBatchAddUrl;
        JSONObject empRequestParam = new JSONObject();
        JSONArray empParamArray = new JSONArray();
        ucUserDtoList.stream().forEach(item -> {
            JSONObject empParam = new JSONObject();
            empParam.put("expEmpId",item.getPersonCode());
            empParam.put("empName",item.getUserName());
            empParam.put("empGender","0");
            empParam.put("empExpDeptId",item.getDeptPk());
            empParam.put("bookPlcName",item.getRankName());
            empParam.put("mobileNo",item.getPhone());
            empParam.put("uEmail",item.getEmail());
            empParamArray.add(empParam);
        });
        empRequestParam.put("appId",configObject.getString("appId"));
        empRequestParam.put("employeeList",empParamArray);
        logger.info("北方假日人员信息批量添加" + empRequestParam.toJSONString());
        String strResult = HttpClientUtil.doPostJsonForm(url, empRequestParam.toJSONString());
        logger.info("北方假日人员信息批量添加结果" + strResult);
        if (StringUtil.isNotEmpty(strResult)){
            JSONObject rs = JSONObject.parseObject(strResult);
            if ("0".equals(rs.getString("ret"))){
                return new ThirdResult(true, rs.getString("msg") );
            }else {
                return new ThirdResult(false, rs.getString("msg") );
            }
        }
        return new ThirdResult(false, strResult );
    }


    @Override
    public ThirdResult queryEmpInfo(String phone,String tenant) {
        UcUserDto userDto = userCenterService.getCompleteUcUserDtoByPhone(phone, tenant);
        String url = empQueryUrl;
        BriChannel enableChannelByOpenType = briChannelService.getEnableChannelByOpenType(tenant, ChannelEnum.BFJR.getName(), 2);
        String config = enableChannelByOpenType.getConfig();
        JSONObject configObject = JSONObject.parseObject(config);
        JSONObject requestParam = new JSONObject();
        requestParam.put("appId",configObject.getString("appId"));
        logger.info("北方假日员工信息查询" + requestParam.toJSONString());
        String strResult = HttpClientUtil.doPostJsonForm(url, requestParam.toJSONString());
        logger.info("北方假日员工信息查询结果" + strResult);
        if (StringUtil.isNotEmpty(strResult)){
            JSONObject rs = JSONObject.parseObject(strResult);
            if ("0".equals(rs.getString("ret"))){
                return new ThirdResult(true, rs.getString("msg") );
            }else {
                return new ThirdResult(false, rs.getString("msg") );
            }
        }
        return new ThirdResult(false, strResult );

    }


    @Override
    public ThirdResult delEmpInfo(String phone,String tenant) {
        BriChannel enableChannelByOpenType = briChannelService.getEnableChannelByOpenType(tenant, ChannelEnum.BFJR.getName(), 2);
        String config = enableChannelByOpenType.getConfig();
        JSONObject configObject = JSONObject.parseObject(config);
        UcUserDto userDto = userCenterService.getCompleteUcUserDtoByPhone(phone, tenant);
        String url = empDelUrl;
        JSONObject requestParam = new JSONObject();
        if (userDto == null) {
            return new ThirdResult(false,"通过手机号和租户查询的UcUserDto为空");
        }
        requestParam.put("appId",configObject.getString("appId"));
        requestParam.put("expEmpId",userDto.getPersonCode());
        logger.info("北方假日人员信息删除" + requestParam.toJSONString());
        String strResult = HttpClientUtil.doPostJsonForm(url, requestParam.toJSONString());
        logger.info("北方假日人员信息删除结果" + strResult);
        if (StringUtil.isNotEmpty(strResult)){
            JSONObject rs = JSONObject.parseObject(strResult);
            if ("0".equals(rs.getString("ret"))){
                return new ThirdResult(true, rs.getString("msg") );
            }else {
                return new ThirdResult(false, rs.getString("msg") );
            }
        }
        return new ThirdResult(false, strResult );

    }



}
